#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
NeuroSky数据采集器使用示例

本文件展示如何使用NeuroPyCollector进行EEG数据采集：
- 基本的设备连接和数据采集
- 回调函数的设置和使用
- 数据记录和会话管理
- 错误处理和资源清理

使用方法：
1. 确保NeuroSky设备已连接到指定串口
2. 运行此脚本开始数据采集
3. 按Ctrl+C停止采集
"""

import time
import signal
import sys
from pathlib import Path

# 添加项目路径
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

from log_sleep.neuropy_collector import NeuroPyCollector
from log_sleep.sleep_logger import SleepLogger


class DataCollectionDemo:
    """
    数据采集演示类
    """
    
    def __init__(self, port="COM5", use_simulation=True):
        """
        初始化演示
        
        Args:
            port: 串口号
            use_simulation: 是否使用模拟模式
        """
        self.port = port
        self.use_simulation = use_simulation
        self.collector = None
        self.logger = None
        self.session_id = None
        
        # 数据统计
        self.data_received = 0
        self.quality_events = 0
        self.start_time = None
        
        # 设置信号处理
        signal.signal(signal.SIGINT, self._signal_handler)
    
    def _signal_handler(self, signum, frame):
        """
        处理Ctrl+C信号
        """
        print("\n接收到停止信号，正在关闭...")
        self.stop_collection()
        sys.exit(0)
    
    def data_callback(self, data):
        """
        数据回调函数
        
        Args:
            data: 包含EEG数据的字典
        """
        self.data_received += 1
        
        # 每100个数据点显示一次统计
        if self.data_received % 100 == 0:
            elapsed = time.time() - self.start_time if self.start_time else 0
            rate = self.data_received / elapsed if elapsed > 0 else 0
            
            print(f"\r数据点: {self.data_received:6d} | "
                  f"采样率: {rate:6.1f} Hz | "
                  f"EEG: {data['eeg_value']:6d} | "
                  f"质量: {data['signal_quality']:3d} | "
                  f"注意力: {data['attention']:2d} | "
                  f"冥想: {data['meditation']:2d}", end="")
    
    def quality_callback(self, quality):
        """
        信号质量回调函数
        
        Args:
            quality: 信号质量值 (0=良好, >0=差)
        """
        self.quality_events += 1
        
        if quality == 0:
            status = "良好"
        elif quality == 200:
            status = "丢失"
        else:
            status = f"差({quality})"
        
        # 只在质量变化时显示
        if quality != 0:
            print(f"\n[质量警告] 信号{status}")
    
    def setup_logging(self):
        """
        设置日志记录
        """
        print("设置日志记录...")
        
        # 创建日志管理器
        self.logger = SleepLogger(
            log_dir="demo_logs",
            file_prefix="collection_demo"
        )
        
        # 创建会话
        timestamp = time.strftime("%Y%m%d_%H%M%S")
        self.session_id = self.logger.create_session_log(f"demo_session_{timestamp}")
        
        print(f"会话ID: {self.session_id}")
        print(f"日志目录: {self.logger.log_dir}")
    
    def setup_collector(self):
        """
        设置数据采集器
        """
        print(f"初始化数据采集器 (端口: {self.port})...")
        
        # 创建采集器
        self.collector = NeuroPyCollector(
            port=self.port,
            logger=self.logger
        )
        
        # 强制使用模拟模式（如果需要）
        if self.use_simulation:
            self.collector.simulation_mode = True
            print("使用模拟模式")
        
        # 设置回调函数
        self.collector.set_data_callback(self.data_callback)
        self.collector.set_quality_callback(self.quality_callback)
        
        print("回调函数已设置")
    
    def start_collection(self):
        """
        开始数据采集
        """
        print("\n开始数据采集...")
        
        # 连接设备
        if not self.collector.connect():
            print("设备连接失败！")
            return False
        
        print("设备连接成功")
        
        # 开始采集
        if not self.collector.start_collection():
            print("无法启动数据采集！")
            return False
        
        print("数据采集已启动")
        print("按 Ctrl+C 停止采集\n")
        
        self.start_time = time.time()
        return True
    
    def stop_collection(self):
        """
        停止数据采集
        """
        if self.collector:
            print("\n\n停止数据采集...")
            self.collector.stop_collection()
            
            # 显示统计信息
            stats = self.collector.get_statistics()
            print("\n=== 采集统计 ===")
            for key, value in stats.items():
                print(f"{key}: {value}")
            
            print(f"\n=== 会话统计 ===")
            print(f"接收数据点: {self.data_received}")
            print(f"质量事件: {self.quality_events}")
            
            if self.start_time:
                duration = time.time() - self.start_time
                print(f"采集时长: {duration:.1f} 秒")
                if duration > 0:
                    print(f"平均采样率: {self.data_received / duration:.1f} Hz")
            
            # 关闭采集器
            self.collector.close()
            print("采集器已关闭")
        
        if self.logger:
            # 导出数据
            print("\n导出数据...")
            try:
                exported_files = self.logger.export_logs()
                print("导出的文件:")
                for file_path in exported_files:
                    print(f"  {file_path}")
            except Exception as e:
                print(f"导出数据时发生错误: {e}")
                # 显示当前日志文件
                print("当前日志文件:")
                log_dir = Path(self.logger.log_dir)
                if log_dir.exists():
                    for file_path in log_dir.glob("*.csv"):
                        size = file_path.stat().st_size
                        print(f"  {file_path.name}: {size} bytes")
                    for file_path in log_dir.glob("*.log"):
                        size = file_path.stat().st_size
                        print(f"  {file_path.name}: {size} bytes")
            
            # 关闭日志
            self.logger.close()
            print("日志管理器已关闭")
    
    def run_demo(self, duration=None):
        """
        运行演示
        
        Args:
            duration: 采集持续时间（秒），None表示无限制
        """
        try:
            # 设置组件
            self.setup_logging()
            self.setup_collector()
            
            # 开始采集
            if not self.start_collection():
                return
            
            # 运行采集
            if duration:
                print(f"采集将运行 {duration} 秒...")
                time.sleep(duration)
                self.stop_collection()
            else:
                # 无限运行直到用户中断
                try:
                    while True:
                        time.sleep(1)
                except KeyboardInterrupt:
                    pass
        
        except Exception as e:
            print(f"\n演示过程中发生错误: {e}")
            import traceback
            traceback.print_exc()
        
        finally:
            self.stop_collection()


def main():
    """
    主函数
    """
    print("NeuroSky数据采集演示")
    print("=" * 50)
    
    # 配置参数
    PORT = "COM5"  # 根据实际情况修改
    USE_SIMULATION = True  # 设为False使用真实设备
    DURATION = 10  # 采集时长（秒），设为None无限制
    
    print(f"配置:")
    print(f"  端口: {PORT}")
    print(f"  模拟模式: {USE_SIMULATION}")
    print(f"  持续时间: {DURATION if DURATION else '无限制'} 秒")
    print()
    
    # 创建并运行演示
    demo = DataCollectionDemo(
        port=PORT,
        use_simulation=USE_SIMULATION
    )
    
    demo.run_demo(duration=DURATION)
    
    print("\n演示完成！")


if __name__ == "__main__":
    main()